package com.imy.lua.lib.image;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;

import androidx.annotation.NonNull;

import com.immomo.mls.LuaViewManager;
import com.immomo.mls.annotation.LuaClass;
import com.immomo.mls.annotation.LuaBridge;
import com.imy.common.util.ALog;
import com.imy.common.util.ColorUtils;
import com.imy.lua.helper.PointScaleHelper;
import com.imy.lua.helper.color.ImageColorHelper;
import com.imy.lua.helper.opencv.ImageFindHelper;
import com.imy.lua.helper.opencv.TemplateMatching;
import com.imy.lua.helper.properties.PropertiesLoaderHelper;
import com.imy.lua.udmapping.bitmap.UDBitmap;
import com.imy.lua.udmapping.point.UDLocationPoint;

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.opencv.core.Rect;

import java.io.File;

/**
 * Created by MLN Template
 * 注册方法：
 * new MLSBuilder.SIHolder(UDImage.LUA_CLASS_NAME, UDImage.class)
 */
@LuaClass
public class UDImage {
    private boolean autoMetrics=false;
    /**
     * Lua类型，Lua调用方法（和静态调用相同）：
     * Image:method()
     */
    public static final String LUA_CLASS_NAME = "Image";


    @LuaBridge
    public void setAutoMetrics(boolean b){
        this.autoMetrics=b;
    }
    /**
     * 从区域中找色
     *
     * @param path
     * @param color
     * @param startX
     * @param startY
     * @param width
     * @param height
     * @param dim
     * @return 返回坐标在屏幕的位置
     */
    @LuaBridge
    public UDLocationPoint findColorInRegion(String path, String color,
                                             int startX, int startY, int width,
                                             int height, float dim) {

        Point point = ImageColorHelper.findColor(BitmapFactory.decodeFile(path), color,
                changeX(startX), changY(startY), changeX(width), changY(height), dim);
        if (point == null) {
            return null;
        }
        return new UDLocationPoint(globals, point);
    }

    private int changY(int startY) {
        if (!autoMetrics){
            return startY;
        }
        return PointScaleHelper.get().changY(startY);
    }

    private int changeX(int startX) {
        if (!autoMetrics){
            return startX;
        }
        return PointScaleHelper.get().changeX(startX);
    }


    /**
     * 多点找色
     *
     * @param path
     * @param luaTable
     * @param dim
     * @return 如果找到则返回第一个点的坐标 否则返回空
     */
    @LuaBridge
    public UDLocationPoint findMultiColors(String path, LuaTable luaTable, float dim) {
        Point mPoint = null;
        for (int i = 1; i < luaTable.getn() + 1; i++) {
            LuaValue luaValue1 = luaTable.get(i);
            int x = luaValue1.get(1).toInt();
            int y = luaValue1.get(2).toInt();
            String color = luaValue1.get(3).toJavaString();
            Point point = ImageColorHelper.isColorMath(BitmapFactory.decodeFile(path),
                    changeX(x), changY(y), color, dim);
            if (i == 1) {
                mPoint = point;
            }
        }
        if (mPoint == null) {
            return null;
        }
        return new UDLocationPoint(globals, mPoint);
    }


    @LuaBridge
    public UDLocationPoint findColor(String path, String color, float dim) {
        Point point = ImageColorHelper.findColor(BitmapFactory.decodeFile(path), color, dim);
        if (point == null) {
            return null;
        }

        return new UDLocationPoint(globals, point);
    }

    /**
     * 取图片某个点的颜色
     *
     * @param path
     * @param x
     * @param y
     * @return 返回十六进制颜色 不包含alpha值
     */
    @LuaBridge
    public String pixel(String path, int x, int y) {
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        int pixel = bitmap.getPixel(changeX(x),
                changY(y));
        return ColorUtils.integerToHex(pixel);
    }

    public static String tryChangeToAndroidPath(String path) {
        if (path.startsWith("/res/")) {
            String projectRes = PropertiesLoaderHelper.getProjectRes();
            String screenFilePath = ImageFindHelper.get().getScreenFilePath();
            //找对应目录的分辨率文件夹
            String realPath;
            realPath = path.replace("/res", projectRes + "/" + screenFilePath);
            File file = new File(realPath);
            if (file.exists()) {
                ALog.i("对应分辨率有此图片:" + realPath);
                return realPath;
            }
            int scriptWidth = PropertiesLoaderHelper.getScriptWidth();
            path = path.replace("/res", projectRes + "/" + scriptWidth);
            return path;
        }
        return path;
    }

    @LuaBridge
    public UDLocationPoint findImageInRegion(String source, String target,
                                             int x, int y, int width, int height, float threshold) {
        Rect rect = new Rect();
        rect.x = changeX(x);
        rect.y = changY(y);
        rect.width = changeX(width);
        rect.height = changY(height);
        Point image = findImage(source, target, 0.7f, threshold, rect, TemplateMatching.MAX_LEVEL_AUTO);
        if (image == null) {
            return null;
        }
        return new UDLocationPoint(globals, image);
    }

    @LuaBridge
    public UDLocationPoint findImage(LuaValue[] luaValues) {
        Point point = null;
        if (luaValues.length == 2) {
            String source = luaValues[0].toJavaString();
            String target = luaValues[1].toJavaString();
            point = findImage(source, target, 0.7f, 0.9f, null, TemplateMatching.MAX_LEVEL_AUTO);
        } else if (luaValues.length == 3) {
            String source = luaValues[0].toJavaString();
            String target = luaValues[1].toJavaString();
            float v = luaValues[2].toFloat();
            point = findImage(source, target, 0.7f, v, null, TemplateMatching.MAX_LEVEL_AUTO);
        }
        if (point == null) {
            return null;
        }
        return new UDLocationPoint(globals, point);
    }


    private Point findImage(String image, String template, float weakThreshold, float threshold, Rect rect, int maxLevel) {
        //解析转换
        image = tryChangeToAndroidPath(image);
        template = tryChangeToAndroidPath(template);
        ALog.i(" image:" + image + "  template:" + template);
        Point point = ImageFindHelper.get().findImage(image, template, weakThreshold, threshold, rect, maxLevel);
        if (point == null) {
            return null;
        }
//        point.x = PointScaleHelper.get().changeX(point.x);
//        point.y = PointScaleHelper.get().changY(point.y);
        return point;
    }


    //<editor-fold desc="Other Constructor">


    private Globals globals;
    /**
     * Lua构造函数，不需要虚拟机及上下文环境
     * @param init 初始化参数
     */
    //public UDImage(@NonNull LuaValue[] init) {}

    /**
     * Lua构造函数，不需要虚拟机，不关心初始化参数
     */
    //public UDImage() {}
    //</editor-fold>

    /**
     * Lua构造函数
     *
     * @param g    虚拟机
     * @param init 构造方法中传入的参数
     */
    public UDImage(@NonNull Globals g, @NonNull LuaValue[] init) {
        this.globals = g;
        ALog.i("UDImage创建");
    }

    //<editor-fold desc="Bridge API">

    /**
     * 获取上下文，一般情况，此上下文为Activity
     *
     * @param globals 虚拟机，可通过构造函数存储
     */
    protected Context getContext(@NonNull Globals globals) {
        LuaViewManager m = (LuaViewManager) globals.getJavaUserdata();
        return m != null ? m.context : null;
    }

//  裁剪 压缩 保存  ---------------------------------------------以下为对图片的一些操作的api------------------

    /**
     * 读取本地路径的一张图片
     *
     * @param path
     * @return
     */
    @LuaBridge
    public UDBitmap read(String path) {
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        return new UDBitmap(globals, bitmap);
    }

    /**
     * 从bitmap里复制一个全新的bitmap出来
     *
     * @param udBitmap
     * @return
     */
    @LuaBridge
    public UDBitmap copy(UDBitmap udBitmap) {
        Bitmap javaUserdata = udBitmap.getJavaUserdata();
        Bitmap bitmap = Bitmap.createBitmap(javaUserdata, 0, 0, javaUserdata.getWidth(), javaUserdata.getHeight());
        return new UDBitmap(globals, bitmap);
    }


}
